const tool = require('../tools/tool')
// const postWeChatMessage = require('../methods/postWechatMessage')
// const user = require('../methods/user')
// const settings = require('./settings')
const db = require('../db')
const formatDateToMySQL = require('../tools/formatDateToMySQL')

function format(content, sender) {
    return {
        content,
        title: '提示：“截至日期”为此通知的发布时间',
        username: sender
    }
}

async function insertToNotificationsTable(userId, content, sender, link) {

    return await db.insertInto('notifications', {
        userId,
        content,
        isRead: 0,
        sender,
        readTime: null,
        link
    })
}

module.exports = {
    send: {
        toUser: {
            async byOpenId(openId, content, senderName, link, data = {}) {
                let userData = await tool.methods.user().getSingleUserInfoByOpenId(openId, true)
                if (!userData) throw '用户不存在'
                let notifId = await insertToNotificationsTable(userData.id, content, senderName, link, data = {})
                let formated = format(content, senderName)
                if (await tool.methods.settings().getItem('postWeChatMessage')) await tool.methods.postWeChatMessage().toUser.byUserId(userData.id, formated.content, formated.title, formated.username, { notifId })
            },
            async byPhone(phone, content, senderName, link, data = {}) {
                let userData = await tool.methods.user().getSingleUserInfoByPhone(phone, true)
                if (!userData) throw '用户不存在'
                let notifId = await insertToNotificationsTable(userData.id, content, senderName, link, data = {})
                let formated = format(content, senderName)
                if (await tool.methods.settings().getItem('postWeChatMessage')) await tool.methods.postWeChatMessage().toUser.byUserId(userData.id, formated.content, formated.title, formated.username, { notifId })
            },
            async byUserId(userId, content, senderName, link, data = {}) {
                let userData = await tool.methods.user().getSingleUserInfoByUserId(userId, true)
                if (!userData) throw '用户不存在'
                let notifId = await insertToNotificationsTable(userData.id, content, senderName, link, data = {})
                let formated = format(content, senderName)
                if (await tool.methods.settings().getItem('postWeChatMessage')) await tool.methods.postWeChatMessage().toUser.byUserId(userData.id, formated.content, formated.title, formated.username, { notifId })
            },
            async byAccount(account, content, senderName, link, data = {}) {
                let userData = await tool.methods.user().getSingleUserInfoByAccount(account, true)
                if (!userData) throw '用户不存在'
                let notifId = await insertToNotificationsTable(userData.id, content, senderName, link, data = {})
                let formated = format(content, senderName)
                if (await tool.methods.settings().getItem('postWeChatMessage')) await tool.methods.postWeChatMessage().toUser.byUserId(userData.id, formated.content, formated.title, formated.username, { notifId })
            },
        },
        async toDepartment(departmentId, content, senderName, link, role) {
            let users = await db.selectWithParams(`select * from users where departmentId = ? ${role === undefined ? `` : `and role = ?`}`, [departmentId, (() => {
                if (role === undefined) return []
                return [role]
            })()])
            for (let i = 0; i < users.length; i++) {
                let userData = users[i]
                let notifId = await insertToNotificationsTable(userData.id, content, senderName, link, data = {})
                let formated = format(content, senderName)
                if (await tool.methods.settings().getItem('postWeChatMessage')) await tool.methods.postWeChatMessage().toUser.byUserId(userData.id, formated.content, formated.title, formated.username, { notifId })
            }
        },
        async toHandleGroup(campusId, categoryId, content, senderName, link, data = {}) {
            let users = await db.selectWithParams(`select * from permissions where campusId = ? and categoryId = ? and type = 1`, [campusId, categoryId])
            for (let i = 0; i < users.length; i++) {
                let userData = users[i]
                let notifId = await insertToNotificationsTable(userData.userId, content, senderName, link, data = {})
                let formated = format(content, senderName)
                if (await tool.methods.settings().getItem('postWeChatMessage')) await tool.methods.postWeChatMessage().toUser.byUserId(userData.userId, formated.content, formated.title, formated.username, { notifId })
            }
        },
        async toReviewGroup(campusId, categoryId, content, senderName, link, data = {}) {
            let users = await db.selectWithParams(`select * from permissions where campusId = ? and categoryId = ? and type = 2`, [campusId, categoryId])
            for (let i = 0; i < users.length; i++) {
                let userData = users[i]
                let notifId = await insertToNotificationsTable(userData.userId, content, senderName, link, data = {})
                let formated = format(content, senderName)
                if (await tool.methods.settings().getItem('postWeChatMessage')) await tool.methods.postWeChatMessage().toUser.byUserId(userData.userId, formated.content, formated.title, formated.username, { notifId })
            }
        },
        async toRole(role, content, senderName, link, data = {}) {
            let users = await db.selectWithParams(`select * from users where role = ?`, [role])
            for (let i = 0; i < users.length; i++) {
                let userData = users[i]
                let notifId = await insertToNotificationsTable(userData.id, content, senderName, link, data = {})
                let formated = format(content, senderName)
                if (await tool.methods.settings().getItem('postWeChatMessage')) await tool.methods.postWeChatMessage().toUser.byUserId(userData.id, formated.content, formated.title, formated.username, { notifId })
            }
        },
        async toPatrolCreater(patrolId, content, senderName, link, data = {}) {
            const patrol = require('./patrol')
            let patrolInfo = await patrol.getHead(patrolId)
            if (!patrolInfo) throw '巡查不存在'
            const user = require('./user')
            let userData = await tool.methods.user().getSingleUserInfoByUserId(patrolInfo.userId)
            if (!userData) throw '用户不存在'
            let notifId = await insertToNotificationsTable(userData.id, content, senderName, link, data = {})
            let formated = format(content, senderName)
            if (await tool.methods.settings().getItem('postWeChatMessage')) await tool.methods.postWeChatMessage().toUser.byUserId(userData.id, formated.content, formated.title, formated.username, { notifId })
        },
        async toAdmin(content, senderName, link, data = {}) {
            let users = await db.selectWithParams(`select * from users where isAdmin = 1`)
            for (let i = 0; i < users.length; i++) {
                let userData = users[i]
                let notifId = await insertToNotificationsTable(userData.id, content, senderName, link, data = {})
                let formated = format(content, senderName)
                if (await tool.methods.settings().getItem('postWeChatMessage')) await tool.methods.postWeChatMessage().toUser.byUserId(userData.id, formated.content, formated.title, formated.username, { notifId })
            }
        }
    },
    formatItem(item) {
        item.createdAt_read = tool.formatTimeNew(new Date(item.createdAt))
        item.readTime_read = tool.formatTimeNew(new Date(item.readTime))
        if (typeof (item.link) == 'string') {
            item.link = tool.replaceSubstring(item.link, '\n', '!%n')
        }
        try {
            item.link = JSON.parse(item.link)
        } catch (error) {

        }
        if (typeof (item.link.data) == 'string') {
            item.link.data = tool.replaceSubstring(item.link.data, '!%n', '\n')
        }

        return item
    },
    async getList(userId, finalId, size = 10) {
        size = isNaN(parseInt(size)) ? 10 : parseInt(size)
        let re = await db.selectWithParams(`select * from notifications where userId = ? and id <= ? order by id DESC, createdAt DESC limit 0,?`, [
            userId,
            await (async () => {
                if (finalId === undefined) {
                    return 999999999999999
                } else {
                    return parseInt(finalId)
                }
            })(),
            size + 1
        ])
        for (let i = 0; i < re.length; i++) {
            if (!i || tool.formatDateString(re[i - 1].createdAt) != tool.formatDateString(re[i].createdAt)) {
                re[i].topTitle = tool.formatDateString(re[i].createdAt)
            }
        }
        re = await tool.array.format(re, (e) => this.formatItem(e))
        return finalId === undefined ? re : re.slice(1)
    },
    async setRead(notifId) {
        await db.updateById('notifications', notifId, {
            isRead: 1,
            readTime: formatDateToMySQL(new Date())
        })
    },
    async setAllRead(userId) {
        let t = await db.selectWithParams(`select * from notifications where userId = ? and isRead = 0`, [userId])
        let time = formatDateToMySQL(new Date())
        await tool.array.format(t, async (item) => {
            await db.updateById('notifications', item.id, {
                isRead: 1,
                readTime: time
            })
        })
    },
    async getByIds(idArr = []) {
        if (!idArr.length) return []
        return await (async () => {
            let re = await db.select(`select * from notifications where ${(() => {
                let flag = false
                let s = ''
                for (let i = 0; i < idArr.length; i++) {
                    if (flag) {
                        s += ' or '
                    } else {
                        flag = true
                    }
                    s += ` id = ${idArr[i]} `
                }
                return s
            })()}`)
            for (let i = 0; i < re.length; i++) {
                re[i] = {
                    isRead: re[i].isRead,
                    id: re[i].id
                }
            }
            return re
        })()
    },
    async getUnreadNum(userId) {
        return (await db.selectWithParams(`select count(*) as total from notifications where userId = ? and isRead = 0`, [userId]))[0].total
    },
    async getItem(notifId) {
        return (await db.selectWithParams(`select * from notifications where id = ?`, [parseInt(notifId)]))[0]
    },
    async deleteItem(notifId) {
        await db.deleteById('notifications',notifId)
    }
}